package com.taxi.comm.server.mina;

import java.net.InetSocketAddress;

import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.taxi.comm.server.Configuration;
import com.taxi.comm.server.Server;
import com.taxi.comm.server.mina.filter.PMSProtocolCodecFactory;
import com.taxi.comm.server.mina.filter.SessionProcessFilter;
import com.taxi.comm.server.mina.handler.RequestHandler;

/**
 * An implementation of @see{com.huateng.pms.comm.Server} .
 * Use Apache MINA to process the network relative works.
 * 
 * @author Watertao
 *
 */
public class MinaServer implements Server {

	private static final Logger log = LoggerFactory.getLogger(MinaServer.class);
	
	@Override
	public void startup() {
		
        try {
        	Configuration config = Configuration.getInstance();
        	
            // Create an acceptor
            NioSocketAcceptor acceptor = new NioSocketAcceptor(config.getProcessorCnt());

            acceptor.getSessionConfig().setIdleTime(IdleStatus.READER_IDLE, config.getSession().getReadIdle());
//            acceptor.getSessionConfig().setIdleTime(IdleStatus.WRITER_IDLE, config.getSession().getWriteIdle());
            acceptor.getSessionConfig().setReceiveBufferSize(config.getSession().getReceiveBufferSize());
            
            acceptor.setBacklog(config.getBacklog());
            
//            acceptor.getFilterChain().addLast("logFilter", new LoggingFilter());
            
            acceptor.getFilterChain().addLast("executorFilter", 
            	new ExecutorFilter(
            			new OrderedThreadPoolExecutor(config.getExecutorCnt())
            	)
            );
            
            acceptor.getFilterChain().addLast("sessionProcessFilter", 
            	new SessionProcessFilter()
            );
            
            acceptor.getFilterChain().addLast("protocolFilter",
        		new ProtocolCodecFilter(
        				new PMSProtocolCodecFactory()
        		)
            );
            // Set handler
            acceptor.setHandler(new RequestHandler());
            acceptor.bind(new InetSocketAddress(config.getPort()));
            System.out.println("Server now listening on port "+config.getPort() );
            log.info("Server now listening on port {}", config.getPort());
            
        } catch (Exception ex) {
            log.error("Exception", ex);
            System.exit(0);
        }
		
	}

}
